﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Xml;

namespace DevScope.SharePoint.Utils.BulkDelete.Helpers
{
    public static partial class SerializationHelper
    {

        /// <summary>
        /// Serializes the specified obj.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <returns></returns>
        public static string Serialize<T>(T obj)
        {
            using (MemoryStream stream = Serialize<T>(obj, null, null))
            {
                return ByteArrayToString(stream.ToArray());
            }
        }

        /// <summary>
        /// Serializes the specified obj.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <param name="ns">The ns.</param>
        /// <returns></returns>
        public static string Serialize<T>(T obj, XmlSerializerNamespaces ns)
        {
            using (MemoryStream stream = Serialize<T>(obj, null, ns))
            {
                return ByteArrayToString(stream.ToArray());
            }
        }

        /// <summary>
        /// Serializes the specified obj.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <param name="enc">The enc.</param>
        /// <returns></returns>
        public static MemoryStream Serialize<T>(T obj, Encoding enc)
        {
            return Serialize<T>(obj, enc, null);
        }

        /// <summary>
        /// Serializes the specified obj.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <param name="enc">The enc.</param>
        /// <param name="ns">The ns.</param>
        /// <returns></returns>
        public static MemoryStream Serialize<T>(T obj, Encoding enc, XmlSerializerNamespaces ns)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");

            MemoryStream stream = new MemoryStream();

            using (XmlWriter writer = new XmlTextWriter(stream, enc))
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));

                if (ns == null)
                    xs.Serialize(writer, obj);
                else
                    xs.Serialize(writer, obj, ns);
            }

            return stream;
        }

        /// <summary>
        /// Serializes to file.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj">The obj.</param>
        /// <param name="filePath">The file path.</param>
        /// <param name="fileMode">The file mode.</param>
        public static void SerializeToFile<T>(T obj, string filePath, FileMode fileMode)
        {
            if (obj == null)
                throw new ArgumentNullException("obj");

            if (string.IsNullOrEmpty(filePath))
                throw new ArgumentNullException("filePath");

            using (FileStream fs = new FileStream(filePath, fileMode))
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                xs.Serialize(fs, obj);
            }
        }

        //-------------------------------------------------------------------
        //-------------------------------------------------------------------
        //-------------------------------------------------------------------

        /// <summary>
        /// Deserializes from file.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filePath">The file path.</param>
        /// <returns></returns>
        public static T DeserializeFromFile<T>(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
                throw new ArgumentNullException("filePath");

            object obj = null;

            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                obj = xs.Deserialize(fs);
            }

            return (T)obj;
        }

        /// <summary>
        /// Deserializes the specified XML.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xml">The XML.</param>
        /// <returns></returns>
        public static T Deserialize<T>(string xml)
        {
            if (string.IsNullOrEmpty(xml))
                throw new ArgumentNullException("objectXml");

            object obj = null;

            using (StringReader sr = new StringReader(xml))
            {
                XmlSerializer xs = new XmlSerializer(typeof(T));
                obj = xs.Deserialize(sr);
            }

            return (T)obj;
        }


        /// <summary>
        /// Bytes the array to string.
        /// </summary>
        /// <param name="characters">The characters.</param>
        /// <returns></returns>
        private static string ByteArrayToString(Byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding();

            string constructedString = encoding.GetString(characters);

            return (constructedString);
        }

    }
}
